import {
  responseSuccess,
  responseData,
  responseError,
} from '@/share/interface/standard';
import { EXPIRES_IN } from '@/share/config';
import { decryptDataForWechat } from '@/middleware/wechat';
import axios from 'axios';
import { APPID, APP_SECRET } from '@/share/config';
// import { DailyHealthController } from '@/controller/miniProgram/UserController';
import type { NextFunction, Request, Response } from 'express';
import Base from '@/controller/public/MiniBaseController';
const jwt = require('jsonwebtoken');

const ERole = {
  kinsfolk: 'kinsfolk', //'亲属'
  patient: 'patient', //'患者'
};
export class wechatLoginController extends Base {
  async LoginForWechat(
    req: Request,
    res: Response,
    next: NextFunction
  ) {
    const { code, role, phone='', encryptedData, iv } = req.body;

    if (phone && !/^1[3456789]\d{9}$/.test(phone)) {
      return responseError('手机号格式不正确');
    }
    if (
      !role ||
      (role !== ERole.kinsfolk && role !== ERole.patient)
    ) {
      return responseError('角色参数不正确');
    }

    const { data } = await axios({
      method: 'get',
      url: `https://api.weixin.qq.com/sns/jscode2session`,
      params: {
        js_code: code,
        appid: APPID,
        secret: APP_SECRET,
        grant_type: 'authorization_code',
      },
    });
    if (data.errcode) return responseError(data.errmsg);
    req.session_key = data.session_key;
    const { nickName, gender, avatarUrl } = decryptDataForWechat(
      encryptedData,
      iv,
      data.session_key
    );

    let cur_user = await this.userRepository.findOne({
      where: { openid: data.openid },
    });
    // console.log(cur_user)
    // console.log(phone)
    const rel_phone = cur_user?.phone || phone;

    const relation = await this.relationShipRepository.find({
      where: { phone:rel_phone  },
    });

    // 注册
    if (!cur_user) {
      // 如果是亲属，查看relation_ship有没有对应的手机号,没有则不允许注册 
      // *有修改 修改为没有手机号也可以注册，在设置里再触发
      if (role === ERole.kinsfolk) {
        // if (!relation.length) {
        //   return responseData({
        //     code: 2,
        //     msg: '该手机号未被关联,请在患者端关联',
        //     data: '',
        //   });
        // }

        // 关联则允许注册
        cur_user = await this.createUser({
          openid: data.openid,
          nick_name: nickName,
          avatar_url: avatarUrl,
          // relation_ship: relation.map((rel) => ({
          //   ...rel,
          //   users: rel.user, // 亲属绑定患者的信息
          // })),
          phone,
          role,
          gender,
        });
      }
      // 患者正常走流程
      if (role === ERole.patient) {
        cur_user = await this.createUser({
          openid: data.openid,
          nick_name: nickName,
          avatar_url: avatarUrl,
          phone,
          role,
          gender,
        });
      }

      const token = this.generateJwtToken(cur_user);
      return responseSuccess({ token });
    }

    // 登录
    if (role !== cur_user.role) return responseError('角色不匹配');

    // 更新患者数据到亲属
    cur_user = await this.userRepository.save({
      ...cur_user,
      relation_ship: relation.map((rel) => ({
        ...rel,
        users: rel.user, // 亲属绑定患者的信息
      })),
    });

    await this.updateUserVisitList(cur_user);
    const token = this.generateJwtToken(cur_user);
    return responseData({
      code: 1,
      msg: '用户已注册',
      data: { token },
    });
  }

  async createUser({
    openid,
    nick_name,
    avatar_url,
    role,
    gender,
    phone,
    relation_ship = null,
  }) {
    const visit_list = [{ date: new Date().toISOString(), count: 1 }];

    const user = await this.userRepository.save({
      openid,
      nick_name,
      avatar_url,
      phone,
      role,
      gender,
      visit_list: JSON.stringify(visit_list),
      relation_ship,
    });

    await this.dailyHealthRepository.save({
      user: { id: user.id },
    });
    await this.capacityDiaryRepository.save({
      user: { id: user.id },
      user_id: user.id,
    });

    return user;
  }

  async updateUserVisitList(user) {
    const user_visit_list = JSON.parse(user.visit_list || '[]');
    const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD
    let visitRecordForToday = user_visit_list.find(
      (record) => record.date.slice(0, 10) === today
    );

    if (visitRecordForToday) {
      visitRecordForToday.count++;
    } else {
      user_visit_list.push({
        date: new Date().toISOString(),
        count: 1,
      });
    }

    await this.userRepository.update(user.id, {
      visit_list: JSON.stringify(user_visit_list),
    });
  }

  generateJwtToken(user) {
    return jwt.sign(
      {
        openid: user.openid,
        role: user.role,
        sub: user.id,
        phone: user.phone,
        model: 'wechat',
      },
      'type-orm-chf',
      { expiresIn: EXPIRES_IN }
    );
  }

  async generateToken(req: Request) {
    return this.generateJwtToken(req.body);
  }

  // 是否存在用户
  async findOneUser(req: Request) {
    const { code, encryptedData, iv } = req.body;

    const { data } = await axios({
      method: 'get',
      url: `https://api.weixin.qq.com/sns/jscode2session`,
      params: {
        js_code: code,
        appid: APPID,
        secret: APP_SECRET,
        grant_type: 'authorization_code',
      },
    });
    if (data.errcode) return responseError(data.errmsg);
    const user = await this.userRepository.findOne({
      where: { openid: data.openid },
    });
    if (!user) return responseData({code: 201,msg: '用户不存在',data: null});
    return responseSuccess(this.generateJwtToken(user));
  }
}
